package come.demo.widgets.multiplicity;

import android.util.SparseArray;

import java.util.ArrayList;
import java.util.List;

public class MultipleAdapter {
    //    final List<HeaderFooterDataType> mData = new ArrayList<>();
    final SparseArray<DataType> mDataTypes = new SparseArray<>();

    public MultipleAdapter() {

    }

    public boolean notifyItemChanged(int position, Object object) {
        for (int i = 0; i < mDataTypes.size(); ++i) {
            final DataType dataType = mDataTypes.valueAt(i);
            final int currDataSize = dataType.getItemCount();
            if (position >= currDataSize) {
                position -= currDataSize;
            } else {
                return dataType.notifyItemChanged(position, object);
            }
        }
        return false;
    }

    public boolean notifyItemRangeChanged(int position, Object... objects) {
        for (int i = 0; i < mDataTypes.size(); ++i) {
            final DataType dataType = mDataTypes.valueAt(i);
            final int currDataSize = dataType.getItemCount();
            if (position >= currDataSize) {
                position -= currDataSize;
            } else {
                return dataType.notifyItemRangeChanged(position, objects);
            }
        }
        return false;
    }

    public boolean notifyItemInserted(int position, Object object) {
        for (int i = 0; i < mDataTypes.size(); ++i) {
            final DataType dataType = mDataTypes.valueAt(i);
            final int currDataSize = dataType.getItemCount();
            if (position >= currDataSize) {
                position -= currDataSize;
            } else {
                return dataType.notifyItemInserted(position, object);
            }
        }
        return false;
    }

    public boolean notifyItemRangeInserted(int position, Object... objects) {
        for (int i = 0; i < mDataTypes.size(); ++i) {
            final DataType dataType = mDataTypes.valueAt(i);
            final int currDataSize = dataType.getItemCount();
            if (position >= currDataSize) {
                position -= currDataSize;
            } else {
                return dataType.notifyItemRangeInserted(position, objects);
            }
        }
        return false;
    }

    public boolean notifyItemMoved(int position, int toPosition) {
        for (int i = 0; i < mDataTypes.size(); ++i) {
            final DataType dataType = mDataTypes.valueAt(i);
            final int currDataSize = dataType.getItemCount();
            if (position >= currDataSize) {
                position -= currDataSize;
            } else {
                return dataType.notifyItemMoved(position, toPosition);
            }
        }
        return false;
    }

    public boolean notifyItemRemoved(int position) {
        for (int i = 0; i < mDataTypes.size(); ++i) {
            final DataType dataType = mDataTypes.valueAt(i);
            final int currDataSize = dataType.getItemCount();
            if (position >= currDataSize) {
                position -= currDataSize;
            } else {
                return dataType.notifyItemRemoved(position);
            }
        }
        return false;
    }

    public boolean notifyItemRangeRemoved(int position, int itemCount) {
        for (int i = 0; i < mDataTypes.size(); ++i) {
            final DataType dataType = mDataTypes.valueAt(i);
            final int currDataSize = dataType.getItemCount();
            if (position >= currDataSize) {
                position -= currDataSize;
            } else {
                return dataType.notifyItemRangeRemoved(position, itemCount);
            }
        }
        return false;
    }


    public void removeAll() {
        mDataTypes.clear();
    }

    public int removeSingleDataType(int index) {
        final int kIndex = mDataTypes.indexOfKey(index);
        if (kIndex < 0)
            return 0;

        final DataType dataType = mDataTypes.valueAt(kIndex);
        mDataTypes.removeAt(kIndex);
        return dataType.getItemCount();
    }

    public boolean remove(int position) {
        for (int i = 0; i < mDataTypes.size(); ++i) {
            final DataType dataType = mDataTypes.valueAt(i);
            final int currDataSize = dataType.getItemCount();
            if (position >= currDataSize) {
                position -= currDataSize;
            } else {
                return dataType.remove(position);
            }
        }
        throw new IllegalStateException("out of range");
    }


    public void add(int index, DataType dataType) {
        dataType.generateTypes(index);
        mDataTypes.put(index, dataType);
    }

    /**
     * 根据ListView或RecyclerVeiw的item position生成type
     */

    public final int getItemType(int position) {
        for (int i = 0; i < mDataTypes.size(); ++i) {
            final DataType dataType = mDataTypes.valueAt(i);
            final int currDataSize = dataType.getItemCount();
            if (position >= currDataSize) {
                position -= currDataSize;
            } else {
                return dataType.getItemType(position);
            }
        }
        throw new IllegalStateException("not found DataType");
    }

    /**
     * 根据ListView或RecyclerVeiw的item position返回是第几种数据类型
     */
//    public final int getDataTypeIndex(int position) {
//        for (int i = 0; i < mDataTypes.size(); ++i) {
//            final DataType dataType = mDataTypes.valueAt(i);
//
//
//            final int currDataSize = dataType.getItemCount();
//            if (position >= currDataSize) {
//                position -= currDataSize;
//            } else {
//                return mDataTypes.keyAt(i);
//            }
//        }
//        throw new IllegalStateException("out of range");
//    }


    /**
     * 根据type,返回HeaderFooterDataType数据类型
     */
    public final DataType findDataTypeByType(int type) {
        for (int i = 0; i < mDataTypes.size(); ++i) {
            final DataType dataType = mDataTypes.valueAt(i);
            if (dataType.containsType(type)) {
                return dataType;
            }

        }
        return null;
    }

//    public final DataType getDataType(int position) {
//        for (int i = 0; i < mDataTypes.size(); ++i) {
//            final DataType dataType = mDataTypes.valueAt(i);
//
//
//            final int currDataSize = dataType.getItemCount();
//            if (position >= currDataSize) {
//                position -= currDataSize;
//            } else {
//                return dataType;
//            }
//        }
//        throw new IllegalStateException("out of range");
//    }


    public final Object getItem(int position) {
        for (int i = 0; i < mDataTypes.size(); ++i) {
            final DataType dataType = mDataTypes.valueAt(i);


            final int currDataSize = dataType.getItemCount();
            if (position >= currDataSize) {
                position -= currDataSize;
            } else {
                return dataType.getItem(position);
            }
        }
        throw new IllegalStateException("out of range");
    }

//    public int getSingleDataTypeSize(int index) {
//        final int kIndex = mDataTypes.indexOfKey(index);
//        if (kIndex < 0)
//            return 0;
//
//        final DataType dataType = mDataTypes.valueAt(kIndex);
//        return dataType.getItemCount();
//    }


    public final int getItemCount() {
        int size = 0;
        for (int i = 0; i < mDataTypes.size(); ++i) {
            final DataType dataType = mDataTypes.valueAt(i);
            size += dataType.getItemCount();
        }
        return size;
    }


}
